/*
 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package com.sun.corba.se.impl.ior;

import java.util.Iterator;

import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.StreamableValue;

import org.omg.CORBA.TypeCode;

import org.omg.PortableInterceptor.ObjectReferenceTemplate;
import org.omg.PortableInterceptor.ObjectReferenceTemplateHelper;

import com.sun.corba.se.spi.oa.ObjectAdapter;

import com.sun.corba.se.spi.ior.ObjectId;
import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
import com.sun.corba.se.spi.ior.ObjectAdapterId;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.spi.ior.IORFactory;
import com.sun.corba.se.spi.ior.IORTemplate;
import com.sun.corba.se.spi.ior.IORTemplateList;
import com.sun.corba.se.spi.ior.IORFactories;

import com.sun.corba.se.impl.orbutil.ORBUtility;

import com.sun.corba.se.spi.orb.ORB;

/** This is an implementation of the ObjectReferenceTemplate abstract value
* type defined by the portable interceptors IDL.
* Note that this is a direct Java implementation
* of the abstract value type: there is no stateful value type defined in IDL,
* since defining the state in IDL is awkward and inefficient.  The best way
* to define the state is to use internal data structures that can be written
* to and read from CORBA streams.
*/
public class ObjectReferenceTemplateImpl extends ObjectReferenceProducerBase implements ObjectReferenceTemplate, StreamableValue {
    transient private IORTemplate iorTemplate;

    public ObjectReferenceTemplateImpl(InputStream is) {
        super((ORB) (is.orb()));
        _read(is);
    }

    public ObjectReferenceTemplateImpl(ORB orb, IORTemplate iortemp) {
        super(orb);
        iorTemplate = iortemp;
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof ObjectReferenceTemplateImpl))
            return false;

        ObjectReferenceTemplateImpl other = (ObjectReferenceTemplateImpl) obj;

        return (iorTemplate != null) && iorTemplate.equals(other.iorTemplate);
    }

    public int hashCode() {
        return iorTemplate.hashCode();
    }

    // Note that this repository ID must reflect the implementation
    // of the abstract valuetype (that is, this class), not the
    // repository ID of the org.omg.PortableInterceptor.ObjectReferenceTemplate
    // class.  This allows for multiple independent implementations
    // of the abstract valuetype, should that become necessary.
    public static final String repositoryId = "IDL:com/sun/corba/se/impl/ior/ObjectReferenceTemplateImpl:1.0";

    public String[] _truncatable_ids() {
        return new String[] { repositoryId };
    }

    public TypeCode _type() {
        return ObjectReferenceTemplateHelper.type();
    }

    /** Read the data into a (presumably) empty ORTImpl.  This sets the
    * orb to the ORB of the InputStream.
    */
    public void _read(InputStream is) {
        org.omg.CORBA_2_3.portable.InputStream istr = (org.omg.CORBA_2_3.portable.InputStream) is;
        iorTemplate = IORFactories.makeIORTemplate(istr);
        orb = (ORB) (istr.orb());
    }

    /** Write the state to the OutputStream.
     */
    public void _write(OutputStream os) {
        org.omg.CORBA_2_3.portable.OutputStream ostr = (org.omg.CORBA_2_3.portable.OutputStream) os;

        iorTemplate.write(ostr);
    }

    public String server_id() {
        int val = iorTemplate.getObjectKeyTemplate().getServerId();
        return Integer.toString(val);
    }

    public String orb_id() {
        return iorTemplate.getObjectKeyTemplate().getORBId();
    }

    public String[] adapter_name() {
        ObjectAdapterId poaid = iorTemplate.getObjectKeyTemplate().getObjectAdapterId();

        return poaid.getAdapterName();
    }

    public IORFactory getIORFactory() {
        return iorTemplate;
    }

    public IORTemplateList getIORTemplateList() {
        IORTemplateList tl = IORFactories.makeIORTemplateList();
        tl.add(iorTemplate);
        tl.makeImmutable();
        return tl;
    }
}
